using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Configuration;
using System.Diagnostics;

namespace ReportMaintenanceUtility
{
	public partial class frmMain : Form
	{
		#region PRIVATE MEMBERS

		private string			_defaultDir			= string.Empty;
		private string			_currDir			= string.Empty;
		private string			_currName			= string.Empty;
		private string			_prevParm			= string.Empty;
		private string			_saveAsDir			= string.Empty;
		private ReportManager	_reportManager		= null;
		private Parameter		_selectedParameter	= null;
		private Parameter		_templateParameter	= null;
		private bool			_initializing		= false;

		#endregion

		#region CONSTRUCTOR(S)

		public frmMain()
		{
			InitializeComponent();
			
			//HACK: manually set various DataGridView controls to NOT render columns by default, as this property is not visbile in the designer
			this.grdReportParameterDefaultNonQueried.AutoGenerateColumns = false;
			this.grdReportParameterValidValuesList.AutoGenerateColumns = false;
			this.grdTemplateParameterDefaultNonQueried.AutoGenerateColumns = false;
			this.grdTemplateParameterValidValuesList.AutoGenerateColumns = false;

			this._defaultDir = ConfigurationManager.AppSettings["defaultDir"];
			this._reportManager = new ReportManager(ConfigurationManager.AppSettings["template"]);
			this.LoadTemplateParameterList();
		}

		#endregion

		#region INITIALIZATOIN METHOD(S)

		private void LoadReportList()
		{
			FolderBrowserDialog fbd = new FolderBrowserDialog();
			fbd.ShowNewFolderButton = false;
			fbd.RootFolder = Environment.SpecialFolder.Personal;
			if (!string.IsNullOrEmpty(this._defaultDir))
			{
				fbd.SelectedPath = this._defaultDir;
			}

			DialogResult dr = fbd.ShowDialog(this);
			if (dr == DialogResult.OK)
			{
				DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
				List<FileInfo> files = new List<FileInfo>(di.GetFiles("*.rdl", SearchOption.TopDirectoryOnly));

				Report rpt = null;

				this._currDir = fbd.SelectedPath;

				foreach (FileInfo fi in files)
				{
					try
					{
						using (TextReader tr = fi.OpenText())
						{
							XmlSerializer serializer = new XmlSerializer(typeof(Report));
							rpt = (Report)serializer.Deserialize(tr);
						}
					}
					catch (Exception ex)
					{
						Debug.WriteLine(string.Format("Unable to deserialize report {0}!\n{1}", fi.Name, ex.Message));
					}

					if (rpt != null)
					{
						this._reportManager.AddReport(fi, rpt);
						if (!this.lstReportList.Items.Contains(fi.Name))
						{
							this.lstReportList.Items.Add(fi.Name);
						}
					}
				}
			}
			this.mnuUtilities.Enabled = true;
			this.grpFilterBy.Enabled = true;
		}
		private void LoadTemplateParameterList()
		{
			if (this._reportManager.Template != null)
			{
				foreach (KeyValuePair<string, Parameter> kvp in this._reportManager.Template.Parameters)
				{
					this.lstTemplateParameterList.Items.Add(kvp.Key);
				}
				this.lstTemplateParameterList.Enabled = true;
			}
		}

		#endregion

		#region UI STATE CHANGE METHODS

		#region ..... RESET METHODS

		private void ResetAll()
		{
			this.ResetReports();
			this.ResetParameters();
			this.ResetFilterCriteria();
			this.ToggleStateButtons(false);
			this.ToggleActionButtons();
		}

		private void ResetReports()
		{
			this._initializing = true;

			this._reportManager.ActiveReport = null;
			this._currName = string.Empty;
			this.lstReportList.Items.Clear();
			this.txtReportPath.Text = string.Empty;
			
			this._initializing = false;
		}

		private void ResetParameters()
		{
			this._initializing = true;

			this._selectedParameter = null;
			this.lstReportParameterList.Items.Clear();

			this._initializing = false;

			ResetSettings();
		}

		private void ResetFilterCriteria()
		{
			this._initializing = true;

			this.txtFilterByDatasetName.Text = string.Empty;
			this.txtFilterByParmName.Text = string.Empty;
			this.txtFilterBySprocName.Text = string.Empty;

			this._initializing = false;
		}

		private void ResetSettings()
		{
			this.ResetReportParameterSettings();
			this.ResetTemplateParameterSettings();
		}

		private void ResetReportParameterSettings()
		{
			this._initializing = true;

			//todo: disable report parameter group panel
			this.grpReportParameter.Enabled = false;

			//textbox state
			this.txtReportParameterName.Text = string.Empty;
			this.txtReportParameterPrompt.Text = string.Empty; ;
			this.rtbReportParameterDefaultCommandText.Text = string.Empty;
			this.rtbReportParameterValidValuesCommandText.Text = string.Empty;

			//label color
			this.lblReportParameterName.ForeColor = Color.Black;
			this.lblReportParameterDataType.ForeColor = Color.Black; ;
			this.lblReportParameterPrompt.ForeColor = Color.Black;

			this.lblReportParameterValidValuesCommandText.ForeColor = Color.Black;
			this.lblReportParameterValidValuesCommandType.ForeColor = Color.Black;
			this.lblReportParameterValidValuesDataset.ForeColor = Color.Black;
			this.lblReportParameterValidValuesLabelField.ForeColor = Color.Black;
			this.lblReportParameterValidValuesValueField.ForeColor = Color.Black;

			this.lblReportParameterDefaultCommandText.ForeColor = Color.Black;
			this.lblReportParameterDefaultCommandType.ForeColor = Color.Black;
			this.lblReportParameterDefaultDataset.ForeColor = Color.Black;
			this.lblReportParameterDefaultNonQueried.ForeColor = Color.Black;
			this.lblReportParameterDefaultValueField.ForeColor = Color.Black;

			//combobox state
			this.cboReportParameterDataType.Items.Clear();
			this.cboReportParameterDefaultCommandType.Items.Clear();
			this.cboReportParameterDefaultDataset.Items.Clear();
			this.cboReportParameterDefaultValueField.Items.Clear();
			this.cboReportParameterValidValuesCommandType.Items.Clear();
			this.cboReportParameterValidValuesDataset.Items.Clear();
			this.cboReportParameterValidValuesLabelField.DataSource = null;
			this.cboReportParameterValidValuesValueField.DataSource = null;

			//checkbox state
			this.cbxReportParameterAllowsBlank.Checked = false;
			this.cbxReportParameterAllowsNull.Checked = false;
			this.cbxReportParameterIsHidden.Checked = false;
			this.cbxReportParameterIsInternal.Checked = false;
			this.cbxReportParameterIsMultiValue.Checked = false;

			//checkbox color
			this.cbxReportParameterAllowsBlank.ForeColor = Color.Black;
			this.cbxReportParameterAllowsNull.ForeColor = Color.Black;
			this.cbxReportParameterIsHidden.ForeColor = Color.Black;
			this.cbxReportParameterIsInternal.ForeColor = Color.Black;
			this.cbxReportParameterIsMultiValue.ForeColor = Color.Black;

			//radio button state
			this.rdoReportParameterDefaultNonQueried.Checked = true;
			this.rdoReportParameterValidValuesNonQueried.Checked = true;

			//radio button color
			this.rdoReportParameterDefaultNonQueried.ForeColor = Color.Black;
			this.rdoReportParameterDefaultNull.ForeColor = Color.Black;
			this.rdoReportParameterDefaultQueried.ForeColor = Color.Black;
			this.rdoReportParameterValidValuesNonQueried.ForeColor = Color.Black;
			this.rdoReportParameterValidValuesQueried.ForeColor = Color.Black;

			//tab state
			this.tabReportParameterValidValues.Select();

			//grids
			this.grdReportParameterDefaultNonQueried.DataSource = null;
			this.grdReportParameterValidValuesList.DataSource = null;

			this._initializing = false;
		}

		private void ResetTemplateParameterSettings()
		{
			this._initializing = true;

			//todo: disable report parameter group panel
			this.grpTemplateParameter.Enabled = false;

			//textbox state
			this.txtTemplateParameterName.Text = string.Empty;
			this.txtTemplateParameterPrompt.Text = string.Empty; ;
			this.rtbTemplateParameterDefaultCommandText.Text = string.Empty;
			this.rtbTemplateParameterValidValuesCommandText.Text = string.Empty;

			//combobox state
			this.cboTemplateParameterDataType.Items.Clear();
			this.cboTemplateParameterDefaultCommandType.Items.Clear();
			this.cboTemplateParameterDefaultDataset.Items.Clear();
			this.cboTemplateParameterDefaultValueField.Items.Clear();
			this.cboTemplateParameterValidValuesCommandType.Items.Clear();
			this.cboTemplateParameterValidValuesDataset.Items.Clear();
			this.cboTemplateParameterValidValuesLabelField.DataSource = null;
			this.cboTemplateParameterValidValuesValueField.DataSource = null;

			//checkbox state
			this.cbxTemplateParameterAllowsBlank.Checked = false;
			this.cbxTemplateParameterAllowsNull.Checked = false;
			this.cbxTemplateParameterIsHidden.Checked = false;
			this.cbxTemplateParameterIsInternal.Checked = false;
			this.cbxTemplateParameterIsMultiValue.Checked = false;

			//checkbox color
			this.cbxTemplateParameterAllowsBlank.ForeColor = Color.Black;
			this.cbxTemplateParameterAllowsNull.ForeColor = Color.Black;
			this.cbxTemplateParameterIsHidden.ForeColor = Color.Black;
			this.cbxTemplateParameterIsInternal.ForeColor = Color.Black;
			this.cbxTemplateParameterIsMultiValue.ForeColor = Color.Black;

			//radio button state
			this.rdoTemplateParameterDefaultNonQueried.Checked = true;
			this.rdoTemplateParameterValidValuesNonQueried.Checked = true;

			//radio button color
			this.rdoTemplateParameterDefaultNonQueried.ForeColor = Color.Black;
			this.rdoTemplateParameterDefaultNull.ForeColor = Color.Black;
			this.rdoTemplateParameterDefaultQueried.ForeColor = Color.Black;
			this.rdoTemplateParameterValidValuesNonQueried.ForeColor = Color.Black;
			this.rdoTemplateParameterValidValuesQueried.ForeColor = Color.Black;

			//tab state
			this.tabTemplateParameterValidValues.Select();

			//grids
			this.grdTemplateParameterDefaultNonQueried.DataSource = null;
			this.grdTemplateParameterValidValuesList.DataSource = null;

			this._initializing = false;
		}

		#endregion

		#region ..... POPULATE METHODS

		private void PopulateSettings()
		{
			this.PopulateReportParameterSettings();

			if (this._reportManager.Template.Parameters.ContainsKey(this._selectedParameter.Name))
			{
				this._templateParameter = this._reportManager.Template.Parameters[this._selectedParameter.Name];
				this.PopulateTemplateParameterSettings();
				this.HighlightDifferences();
			}
			else
			{
				this._templateParameter = null;
			}
	}

		private void PopulateReportParameterSettings()
		{
			this._initializing = true;

			//make sure the report paramter settings panel is enabled...
			this.grpReportParameter.Enabled = true;

			#region MISC ATTRIBUTES

			//set the text controls that correspond to the parameter's name and prompt values
			this.txtReportParameterName.Text = this._selectedParameter.Name;
			this.txtReportParameterPrompt.Text = (this._selectedParameter.Prompt == null ? string.Empty : this._selectedParameter.Prompt);

			//populate the data-type combobox from the list of data-type enums...
			this.cboReportParameterDataType.Items.AddRange(Enum.GetNames(typeof(ReportParameterTypeDataType)));

			//set the combobox selected item equal (=) to the report parameter's data-type
			this.cboReportParameterDataType.SelectedItem = Enum.GetName(typeof(ReportParameterTypeDataType), this._selectedParameter.DataType);

			//set the checkbox controls that correspond to the report parameters misc attributes...
			this.cbxReportParameterAllowsBlank.Checked = this._selectedParameter.AllowBlank;
			this.cbxReportParameterAllowsNull.Checked = this._selectedParameter.Nullable;
			this.cbxReportParameterIsHidden.Checked = this._selectedParameter.Hidden;
			this.cbxReportParameterIsInternal.Checked = (this._selectedParameter.Internal);
			this.cbxReportParameterIsMultiValue.Checked = this._selectedParameter.MultiValue;

			#endregion

			#region AVAILABLE VALUES

			DataSet ds = this._selectedParameter.ValuesDataSet;	//try and get reference to dataset
			if (ds != null)
			{
				//dataset referece exists.. so populate controls accordingly...

				//radio button selection
				this.rdoReportParameterValidValuesQueried.Checked = true;

				//populate the valid values data set controls and set panel visibility...
				this.PopulateReportParameterDataSetControls(ds, ValueType.ValidValues);
			}
			else 
			{
				//ValidValues.DataSet does not exists, so default to a list...

				//radio button selection
				this.rdoReportParameterValidValuesNonQueried.Checked = true;

				//populate the valid values datagrid control and set panel visibility
				this.PopulateReportParameterDataGrid(ValueType.ValidValues);
			}
			#endregion

			#region DEFAULT VALUES
			ds = this._selectedParameter.DefaultDataSet;
			if (ds != null)
			{
				//dataset reference exists.. so populate controls accordingly...

				//radio button selection
				this.rdoReportParameterDefaultQueried.Checked = true;

				//populate the Default Values data set controls and set panel visibility...
				this.PopulateReportParameterDataSetControls(ds, ValueType.DefaultValues);
			}
			else if (this._selectedParameter.Nullable && (this._selectedParameter.DefaultValue == null || !this._selectedParameter.DefaultValue.HasData))
			{
				//panel visibility and radio button selection
				this.rdoReportParameterDefaultNull.Checked = true;
				this.pnlReportParameterDefaultNonQueried.Visible = false;
				this.pnlReportParameterDefaultQueried.Visible = false;
			}
			else
			{
				//panel visibility and radio button selection
				this.pnlReportParameterDefaultNonQueried.Visible = true;

				//populate the default values datagrid control and set panel visibility
				this.PopulateReportParameterDataGrid(ValueType.DefaultValues);
			}
			#endregion

			if (this._selectedParameter.IsDirty)
			{
				this._selectedParameter.SaveState();
			}
			this._initializing = false;
		}

		private void PopulateReportParameterDataSetControls(DataSet ds, ValueType vt)
		{
			//create list of all available DataSets that exist within the current report...
			List<string> dsNames = new List<string>(this._reportManager.ActiveReport.DataSets.Keys);

			switch (vt)
			{
				case ValueType.ValidValues:

					this.pnlReportParameterValidValuesQueried.Visible = true;
					this.pnlReportParameterValidValuesNonQueried.Visible = false;

					//populate the ValidValues DataSet combobox with the resulting list...
					this.cboReportParameterValidValuesDataset.Items.AddRange(dsNames.ToArray());

					//set the combo box's selected item to match the report parameter's data-set name
					cboReportParameterValidValuesDataset.SelectedItem = ds.Name;

					//DataSet.Fields
					this.PopulateReportParameterDataFields(ds, vt);

					//DataSet.Query
					this.PopulateReportParameterDataQuery(ds, vt);

					break;

				case ValueType.DefaultValues:

					this.pnlReportParameterDefaultQueried.Visible = true;
					this.pnlReportParameterDefaultNonQueried.Visible = false;

					//populate the DefaultValues DataSet combobox with the resulting list...
					this.cboReportParameterDefaultDataset.Items.AddRange(dsNames.ToArray());

					//set the combo box's selected item to match the report parameter's data-set name
					cboReportParameterDefaultDataset.SelectedItem = ds.Name;

					//DataSet.Fields
					this.PopulateReportParameterDataFields(ds, vt);

					//DataSet.Query
					this.PopulateReportParameterDataQuery(ds, vt);

					break;
			}
		}

		private void PopulateReportParameterDataFields(DataSet ds, ValueType vt)
		{
			if (ds.Fields.Count > 0)
			{
				//list of fields
				List<string> fields = new List<string>();
				foreach (Field f in ds.Fields)
				{
					fields.Add(f.Name);
				}

				switch (vt)
				{
					case ValueType.ValidValues:

						//populate both the labels and values comboboxes from the list of available fields returned by the query...
						this.cboReportParameterValidValuesLabelField.Items.AddRange(fields.ToArray());
						this.cboReportParameterValidValuesValueField.Items.AddRange(fields.ToArray());

						//if a Label field has been specified in the data set reference, set the label combobox accordingly...
						if (!string.IsNullOrEmpty(this._selectedParameter.ValidValues.DataSetReference.LabelField))
						{
							this.cboReportParameterValidValuesLabelField.SelectedItem = this._selectedParameter.ValidValues.DataSetReference.LabelField;
						}

						//if a Value field has been specified in the data set reference, set the vabel combobox accordingly...
						if (!string.IsNullOrEmpty(this._selectedParameter.ValidValues.DataSetReference.ValueField))
						{
							this.cboReportParameterValidValuesValueField.SelectedItem = this._selectedParameter.ValidValues.DataSetReference.ValueField;
						}

						break;

					case ValueType.DefaultValues:

						//populate the Default values comboboxe from the list of available fields returned by the query...
						this.cboReportParameterDefaultValueField.Items.AddRange(fields.ToArray());

						//if a Value field has been specified in the data set reference, set the vabel combobox accordingly...
						if (!string.IsNullOrEmpty(this._selectedParameter.DefaultValue.ValidValues.DataSetReference.ValueField))
						{
							this.cboReportParameterDefaultValueField.SelectedItem = this._selectedParameter.DefaultValue.ValidValues.DataSetReference.ValueField;
						}

						break;
				}
			}
		}

		private void PopulateReportParameterDataQuery(DataSet ds, ValueType vt)
		{
			if (ds.Query != null)
			{
				//get the string based name of the report paraemter query's command-type
				string cmdType = Enum.GetName(typeof(QueryTypeCommandType), ds.Query.CommandType);

				switch (vt)
				{
					case ValueType.ValidValues:

						//populate the command type combobox from the list of command type enums...
						this.cboReportParameterValidValuesCommandType.Items.AddRange(Enum.GetNames(typeof(QueryTypeCommandType)));

						//set the combobox selected item equal (=) to the command type
						this.cboReportParameterValidValuesCommandType.SelectedItem = cmdType;

						//set the command text control
						this.rtbReportParameterValidValuesCommandText.Text = ds.Query.CommandText;
						
						break;

					case ValueType.DefaultValues:

						//populate the command type combobox from the list of command type enums...
						this.cboReportParameterDefaultCommandType.Items.AddRange(Enum.GetNames(typeof(QueryTypeCommandType)));

						//set the combobox selected item equal (=) to the command type
						this.cboReportParameterDefaultCommandType.SelectedItem = cmdType;

						//set the command text control
						this.rtbReportParameterDefaultCommandText.Text = ds.Query.CommandText;
						
						break;
				}
			}
		}

		private void PopulateReportParameterDataGrid(ValueType vt)
		{
			switch (vt)
			{
				case ValueType.ValidValues:

					this.pnlReportParameterValidValuesNonQueried.Visible = true;
					this.pnlReportParameterValidValuesQueried.Visible = false;

					//if a ValidValues object object does not already exist, create a new, empty one (THIS STEP IS CRITICAL!!!)
					if (this._selectedParameter.ValidValues == null || this._selectedParameter.ValidValues.ValuesList == null)
					{
						this._selectedParameter.CreateValidValues();
					}

					//set the grid's datasource to the new value lsit
					this.grdReportParameterValidValuesList.DataSource = this._selectedParameter.ValidValues.ValuesList;
					break;

				case ValueType.DefaultValues:

					this.rdoReportParameterDefaultNonQueried.Checked = true;
					this.pnlReportParameterDefaultQueried.Visible = false;

					//only display & populate grid if parameter is MultiValue, otherwise display single textbox field instead
					if (this._selectedParameter.MultiValue)
					{
						this.txtReportParameterDefaultNonQueried.Visible = false;
						this.grdReportParameterDefaultNonQueried.Visible = true;

						if (this._selectedParameter.DefaultValue == null || !this._selectedParameter.DefaultValue.HasData) //this._selectedParameter.DefaultValue.ValidValues == null || this._selectedParameter.DefaultValue.ValidValues.DefaultList == null
						{
							this._selectedParameter.CreateDefaultValues();
						}

						this.grdReportParameterDefaultNonQueried.DataSource = this._selectedParameter.DefaultValue.ValidValues.DefaultList;
					}
					else
					{
						this.txtReportParameterDefaultNonQueried.Visible = true;
						this.grdReportParameterDefaultNonQueried.Visible = false;

						if (this._selectedParameter.DefaultValue == null || !this._selectedParameter.DefaultValue.HasData)
						{
							this._selectedParameter.CreateDefaultValues();
						}

						this.txtReportParameterDefaultNonQueried.Text = this._selectedParameter.DefaultValue.ValidValues.DefaultList[0].Value;
					}

					break;
			}

		}

		#region ..... POPULATE TEMPLATE PARAMETERS

		private void PopulateTemplateParameterSettings()
		{
			this._initializing = true;

			#region MISC ATTRIBUTES

			//set the text controls that correspond to the parameter's name and prompt values
			this.txtTemplateParameterName.Text = this._templateParameter.Name;
			this.txtTemplateParameterPrompt.Text = (this._templateParameter.Prompt == null ? string.Empty : this._templateParameter.Prompt);

			//populate the data-type combobox from the list of data-type enums...
			this.cboTemplateParameterDataType.Items.AddRange(Enum.GetNames(typeof(ReportParameterTypeDataType)));

			//set the combobox selected item equal (=) to the report parameter's data-type
			this.cboTemplateParameterDataType.SelectedItem = Enum.GetName(typeof(ReportParameterTypeDataType), this._templateParameter.DataType);

			//set the checkbox controls that correspond to the report parameters misc attributes...
			this.cbxTemplateParameterAllowsBlank.Checked = this._templateParameter.AllowBlank;
			this.cbxTemplateParameterAllowsNull.Checked = this._templateParameter.Nullable;
			this.cbxTemplateParameterIsHidden.Checked = this._templateParameter.Hidden;
			this.cbxTemplateParameterIsInternal.Checked = (this._templateParameter.Internal);
			this.cbxTemplateParameterIsMultiValue.Checked = this._templateParameter.MultiValue;

			#endregion

			#region AVAILABLE VALUES

			DataSet ds = this._templateParameter.ValuesDataSet;	//try and get reference to dataset
			if (ds != null)
			{
				//dataset referece exists.. so populate controls accordingly...

				//radio button selection
				this.rdoTemplateParameterValidValuesQueried.Checked = true;

				//populate the valid values data set controls and set panel visibility...
				this.PopulateTemplateParameterDataSetControls(ds, ValueType.ValidValues);
			}
			else
			{
				//ValidValues.DataSet does not exists, so default to a list...

				//radio button selection
				this.rdoTemplateParameterValidValuesNonQueried.Checked = true;

				//populate the valid values datagrid control and set panel visibility
				this.PopulateTemplateParameterDataGrid(ValueType.ValidValues);
			}
			#endregion

			#region DEFAULT VALUES
			ds = this._templateParameter.DefaultDataSet;
			if (ds != null)
			{
				//dataset reference exists.. so populate controls accordingly...

				//radio button selection
				this.rdoTemplateParameterDefaultQueried.Checked = true;

				//populate the Default Values data set controls and set panel visibility...
				this.PopulateTemplateParameterDataSetControls(ds, ValueType.DefaultValues);
			}
			else if (this._templateParameter.Nullable && (this._templateParameter.DefaultValue == null || !this._templateParameter.DefaultValue.HasData))
			{
				//panel visibility and radio button selection
				this.rdoTemplateParameterDefaultNull.Checked = true;
				this.pnlTemplateParameterDefaultNonQueried.Visible = false;
				this.pnlTemplateParameterDefaultQueried.Visible = false;
			}
			else
			{
				//panel visibility and radio button selection
				this.pnlTemplateParameterDefaultNonQueried.Visible = true;

				//populate the default values datagrid control and set panel visibility
				this.PopulateTemplateParameterDataGrid(ValueType.DefaultValues);
			}
			#endregion

			if (this._templateParameter.IsDirty)
			{
				this._templateParameter.SaveState();
			}
			this._initializing = false;
		}

		private void PopulateTemplateParameterDataSetControls(DataSet ds, ValueType vt)
		{
			//create list of all available DataSets that exist within the current report...
			List<string> dsNames = new List<string>(this._reportManager.ActiveReport.DataSets.Keys);

			switch (vt)
			{
				case ValueType.ValidValues:

					this.pnlTemplateParameterValidValuesQueried.Visible = true;
					this.pnlTemplateParameterValidValuesNonQueried.Visible = false;

					//populate the ValidValues DataSet combobox with the resulting list...
					this.cboTemplateParameterValidValuesDataset.Items.AddRange(dsNames.ToArray());

					//set the combo box's selected item to match the report parameter's data-set name
					cboTemplateParameterValidValuesDataset.SelectedItem = ds.Name;

					//DataSet.Fields
					this.PopulateTemplateParameterDataFields(ds, vt);

					//DataSet.Query
					this.PopulateTemplateParameterDataQuery(ds, vt);

					break;

				case ValueType.DefaultValues:

					this.pnlTemplateParameterDefaultQueried.Visible = true;
					this.pnlTemplateParameterDefaultNonQueried.Visible = false;

					//populate the DefaultValues DataSet combobox with the resulting list...
					this.cboTemplateParameterDefaultDataset.Items.AddRange(dsNames.ToArray());

					//set the combo box's selected item to match the report parameter's data-set name
					cboTemplateParameterDefaultDataset.SelectedItem = ds.Name;

					//DataSet.Fields
					this.PopulateTemplateParameterDataFields(ds, vt);

					//DataSet.Query
					this.PopulateTemplateParameterDataQuery(ds, vt);

					break;
			}
		}

		private void PopulateTemplateParameterDataFields(DataSet ds, ValueType vt)
		{
			if (ds.Fields.Count > 0)
			{
				//list of fields
				List<string> fields = new List<string>();
				foreach (Field f in ds.Fields)
				{
					fields.Add(f.Name);
				}

				switch (vt)
				{
					case ValueType.ValidValues:

						//populate both the labels and values comboboxes from the list of available fields returned by the query...
						this.cboTemplateParameterValidValuesLabelField.Items.AddRange(fields.ToArray());
						this.cboTemplateParameterValidValuesValueField.Items.AddRange(fields.ToArray());

						//if a Label field has been specified in the data set reference, set the label combobox accordingly...
						if (!string.IsNullOrEmpty(this._templateParameter.ValidValues.DataSetReference.LabelField))
						{
							this.cboTemplateParameterValidValuesLabelField.SelectedItem = this._templateParameter.ValidValues.DataSetReference.LabelField;
						}

						//if a Value field has been specified in the data set reference, set the vabel combobox accordingly...
						if (!string.IsNullOrEmpty(this._templateParameter.ValidValues.DataSetReference.ValueField))
						{
							this.cboTemplateParameterValidValuesValueField.SelectedItem = this._templateParameter.ValidValues.DataSetReference.ValueField;
						}

						break;

					case ValueType.DefaultValues:

						//populate the Default values comboboxe from the list of available fields returned by the query...
						this.cboTemplateParameterDefaultValueField.Items.AddRange(fields.ToArray());

						//if a Value field has been specified in the data set reference, set the vabel combobox accordingly...
						if (!string.IsNullOrEmpty(this._templateParameter.DefaultValue.ValidValues.DataSetReference.ValueField))
						{
							this.cboTemplateParameterDefaultValueField.SelectedItem = this._templateParameter.DefaultValue.ValidValues.DataSetReference.ValueField;
						}

						break;
				}
			}
		}

		private void PopulateTemplateParameterDataQuery(DataSet ds, ValueType vt)
		{
			if (ds.Query != null)
			{
				//get the string based name of the report paraemter query's command-type
				string cmdType = Enum.GetName(typeof(QueryTypeCommandType), ds.Query.CommandType);

				switch (vt)
				{
					case ValueType.ValidValues:

						//populate the command type combobox from the list of command type enums...
						this.cboTemplateParameterValidValuesCommandType.Items.AddRange(Enum.GetNames(typeof(QueryTypeCommandType)));

						//set the combobox selected item equal (=) to the command type
						this.cboTemplateParameterValidValuesCommandType.SelectedItem = cmdType;

						//set the command text control
						this.rtbTemplateParameterValidValuesCommandText.Text = ds.Query.CommandText;

						break;

					case ValueType.DefaultValues:

						//populate the command type combobox from the list of command type enums...
						this.cboTemplateParameterDefaultCommandType.Items.AddRange(Enum.GetNames(typeof(QueryTypeCommandType)));

						//set the combobox selected item equal (=) to the command type
						this.cboTemplateParameterDefaultCommandType.SelectedItem = cmdType;

						//set the command text control
						this.rtbTemplateParameterDefaultCommandText.Text = ds.Query.CommandText;

						break;
				}
			}
		}

		private void PopulateTemplateParameterDataGrid(ValueType vt)
		{
			switch (vt)
			{
				case ValueType.ValidValues:

					this.pnlTemplateParameterValidValuesNonQueried.Visible = true;
					this.pnlTemplateParameterValidValuesQueried.Visible = false;

					//if a ValidValues object object does not already exist, create a new, empty one (THIS STEP IS CRITICAL!!!)
					if (this._templateParameter.ValidValues == null || this._templateParameter.ValidValues.ValuesList == null)
					{
						this._templateParameter.CreateValidValues();
					}

					//set the grid's datasource to the new value lsit
					this.grdTemplateParameterValidValuesList.DataSource = this._templateParameter.ValidValues.ValuesList;
					break;

				case ValueType.DefaultValues:

					this.rdoTemplateParameterDefaultNonQueried.Checked = true;
					this.pnlTemplateParameterDefaultQueried.Visible = false;

					//only display & populate grid if parameter is MultiValue, otherwise display single textbox field instead
					if (this._templateParameter.MultiValue)
					{
						this.txtTemplateParameterDefaultNonQueried.Visible = false;
						this.grdTemplateParameterDefaultNonQueried.Visible = true;

						if (this._templateParameter.DefaultValue == null || !this._templateParameter.DefaultValue.HasData) //this._templateParameter.DefaultValue.ValidValues == null || this._templateParameter.DefaultValue.ValidValues.DefaultList == null
						{
							this._templateParameter.CreateDefaultValues();
						}

						this.grdTemplateParameterDefaultNonQueried.DataSource = this._templateParameter.DefaultValue.ValidValues.DefaultList;
					}
					else
					{
						this.txtTemplateParameterDefaultNonQueried.Visible = true;
						this.grdTemplateParameterDefaultNonQueried.Visible = false;

						if (this._templateParameter.DefaultValue == null || !this._templateParameter.DefaultValue.HasData)
						{
							this._templateParameter.CreateDefaultValues();
						}

						this.txtTemplateParameterDefaultNonQueried.Text = this._templateParameter.DefaultValue.ValidValues.DefaultList[0].Value;
					}

					break;
			}

		}

		#endregion

		#endregion

		#region ..... MISC

		private void Verify(ReportWrapper item)
		{
			if (item != null && item.IsDirty)
			{
				DialogResult dr = MessageBox.Show("You have made changes that have not been saved. Do you wish to save them now?\n[Warning: This action cannot be undone!]", "Save Changes?", MessageBoxButtons.YesNo);
				switch (dr)
				{
					case DialogResult.Yes:
						ReportManager.SaveChanges(item);
						break;

					case DialogResult.No:
						item.RestoreState();
						break;
				}
				this.ToggleStateButtons(false);
			}
		}

		private void HighlightDifferences()
		{
			if (this._templateParameter != null)
			{
				//name
				if (!this.txtReportParameterName.Text.Equals(this.txtTemplateParameterName.Text))
				{
					this.lblReportParameterName.ForeColor = Color.Red;
				}
				//data type
				if (!this.cboReportParameterDataType.Text.Equals(this.cboTemplateParameterDataType.Text))
				{
					this.lblReportParameterDataType.ForeColor = Color.Red;
				}
				//prompt
				if (!this.txtReportParameterPrompt.Text.Equals(this.txtTemplateParameterPrompt.Text))
				{
					this.lblReportParameterPrompt.ForeColor = Color.Red;
				}

				//allows blanks checkbox
				if (this.cbxReportParameterAllowsBlank.Checked != this.cbxTemplateParameterAllowsBlank.Checked)
				{
					this.cbxReportParameterAllowsBlank.ForeColor = Color.Red;
				}
				if (this.cbxReportParameterAllowsNull.Checked != this.cbxTemplateParameterAllowsNull.Checked)
				{
					this.cbxReportParameterAllowsNull.ForeColor = Color.Red;
				}
				if (this.cbxReportParameterIsHidden.Checked != this.cbxTemplateParameterIsHidden.Checked)
				{
					this.cbxReportParameterIsHidden.ForeColor = Color.Red;
				}
				if (this.cbxReportParameterIsInternal.Checked != this.cbxTemplateParameterIsInternal.Checked)
				{
					this.cbxReportParameterIsInternal.ForeColor = Color.Red;
				}
				if (this.cbxReportParameterIsMultiValue.Checked != this.cbxTemplateParameterIsMultiValue.Checked)
				{
					this.cbxReportParameterIsMultiValue.ForeColor = Color.Red;
				}

				//valid values data set
				if (!this.cboReportParameterValidValuesDataset.Text.Equals(this.cboTemplateParameterValidValuesDataset.Text))
				{
					this.lblReportParameterValidValuesDataset.ForeColor = Color.Red;
					this.tabReportParameterValidValues.ForeColor = Color.Red;
				}
				//valid values label field
				if (!this.cboReportParameterValidValuesLabelField.Text.Equals(this.cboTemplateParameterValidValuesLabelField.Text))
				{
					this.lblReportParameterValidValuesLabelField.ForeColor = Color.Red;
				}
				//valid values value field
				if (!this.cboReportParameterValidValuesValueField.Text.Equals(this.cboTemplateParameterValidValuesValueField.Text))
				{
					this.lblReportParameterValidValuesValueField.ForeColor = Color.Red;
				}
				//valid values command type
				if (!this.cboReportParameterValidValuesCommandType.Text.Equals(this.cboTemplateParameterValidValuesCommandType.Text))
				{
					this.lblReportParameterValidValuesCommandType.ForeColor = Color.Red;
				}
				//valid values command text
				if (!this.rtbReportParameterValidValuesCommandText.Text.Equals(this.rtbTemplateParameterValidValuesCommandText.Text))
				{
					this.lblReportParameterValidValuesCommandText.ForeColor = Color.Red;
				}

				//default value data set
				if (!this.cboReportParameterDefaultDataset.Text.Equals(this.cboTemplateParameterDefaultDataset.Text))
				{
					this.lblReportParameterDefaultDataset.ForeColor = Color.Red;
				}
				//default value value field
				if (!this.cboReportParameterDefaultValueField.Text.Equals(this.cboTemplateParameterDefaultValueField.Text))
				{
					this.lblReportParameterDefaultValueField.ForeColor = Color.Red;
				}
				//default value command type
				if (!this.cboReportParameterDefaultCommandType.Text.Equals(this.cboTemplateParameterDefaultCommandType.Text))
				{
					this.lblReportParameterDefaultCommandType.ForeColor = Color.Red;
				}
				//default value command text
				if (!this.rtbReportParameterDefaultCommandText.Text.Equals(this.rtbTemplateParameterDefaultCommandText.Text))
				{
					this.lblReportParameterDefaultCommandText.ForeColor = Color.Red;
				}
				//default non-queried text box value
				if (!this.txtReportParameterDefaultNonQueried.Text.Equals(this.txtTemplateParameterDefaultNonQueried.Text))
				{
					this.lblReportParameterDefaultNonQueried.ForeColor = Color.Red;
				}

				//valid values source (queried vs non-queried)
				if (this.rdoReportParameterValidValuesNonQueried.Checked && !this.rdoReportParameterValidValuesNonQueried.Checked)
				{
					this.rdoReportParameterValidValuesNonQueried.ForeColor = Color.Red;
				}
				else if (this.rdoTemplateParameterValidValuesQueried.Checked && !this.rdoReportParameterValidValuesQueried.Checked)
				{
					this.rdoReportParameterValidValuesQueried.ForeColor = Color.Red;
				}

				//default values source (queried vs non-queried)
				if (this.rdoTemplateParameterDefaultNonQueried.Checked && !this.rdoReportParameterDefaultNonQueried.Checked)
				{
					this.rdoReportParameterDefaultNonQueried.ForeColor = Color.Red;
				}
				else if (this.rdoTemplateParameterDefaultNull.Checked && !this.rdoReportParameterDefaultNull.Checked)
				{
					this.rdoReportParameterDefaultNull.ForeColor = Color.Red;
				}
				else if (this.rdoTemplateParameterDefaultQueried.Checked && !this.rdoReportParameterDefaultQueried.Checked)
				{
					this.rdoReportParameterDefaultQueried.ForeColor = Color.Red;
				}

				//grids
				if (!CompareTo<CustomList<ParameterValue>>.Compare((CustomList<ParameterValue>)this.grdReportParameterValidValuesList.DataSource, (CustomList<ParameterValue>)this.grdTemplateParameterValidValuesList.DataSource))
				{
					this.grdReportParameterValidValuesList.ForeColor = Color.Red;
				}
				if (!CompareTo<CustomList<DefaultValue>>.Compare((CustomList<DefaultValue>)this.grdReportParameterDefaultNonQueried.DataSource, (CustomList<DefaultValue>)this.grdTemplateParameterDefaultNonQueried.DataSource))
				{
					this.grdReportParameterDefaultNonQueried.ForeColor = Color.Red;
				}
			}
		}

		private void ToggleStateButtons(bool state)
		{
			this.btnSaveChanges.Enabled = state;
			this.btnReset.Enabled = state;
		}

		private void ToggleActionButtons()
		{
			if (this._selectedParameter == null && this._templateParameter == null)
			{
				this.grpCopySettings.Enabled = false;
			}
			else
			{
				this.grpCopySettings.Enabled = true;

				if (this._selectedParameter == null && this._templateParameter != null)
				{
					//a template parameter without a matching report parameter is selected...
					if (this.lstReportParameterList.Items.Contains(this._templateParameter.Name))
					{
						this.btnAddTemplateParameterToReport.Enabled = false;
					}
					else
					{
						this.btnAddTemplateParameterToReport.Enabled = true;
					}
					this.btnCopyParameterToTemplate.Enabled = false;
					this.btnCopyTemplateToParameter.Enabled = false;
					this.btnAddReportParameterToTemplate.Enabled = false;
				}
				else if (this._selectedParameter != null && this._templateParameter == null)
				{
					//a report parameter without a matching template parameter is selected...
					if (this.lstTemplateParameterList.Items.Contains(this._selectedParameter.Name))
					{
						this.btnAddReportParameterToTemplate.Enabled = false;
					}
					else
					{
						this.btnAddReportParameterToTemplate.Enabled = true;
					}
					this.btnCopyParameterToTemplate.Enabled = false;
					this.btnCopyTemplateToParameter.Enabled = false;
					this.btnAddTemplateParameterToReport.Enabled = false;
				}
				else
				{
					this.btnCopyParameterToTemplate.Enabled = true;
					this.btnCopyTemplateToParameter.Enabled = true;

					if (this._selectedParameter.Name == this._templateParameter.Name)
					{
						this.btnAddReportParameterToTemplate.Enabled = false;
						this.btnAddTemplateParameterToReport.Enabled = false;
					}
					else
					{
						if (this.lstTemplateParameterList.Items.Contains(this._selectedParameter.Name))
						{
							this.btnAddReportParameterToTemplate.Enabled = false;
						}
						else
						{
							this.btnAddReportParameterToTemplate.Enabled = true;
						}

						if (this.lstReportParameterList.Items.Contains(this._templateParameter.Name))
						{
							this.btnAddTemplateParameterToReport.Enabled = false;
						}
						else
						{
							this.btnAddTemplateParameterToReport.Enabled = true;
						}
					}
				}
			}
		}

		#endregion

		#endregion

		#region EVENT HANDLERS

		#region	..... MENU EVENT HANDLERS

		private void mnuFileOpen_Click(object sender, EventArgs e)
		{
			this.Cursor = Cursors.WaitCursor;
			try
			{
				this.ResetAll();
				this._reportManager.Reports.Clear();
				this.LoadReportList();
				if (this.lstReportList.Items.Count > 0)
				{
					this.lstReportList.SelectedIndex = 0;
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(string.Format("Error loading one or more files from selected directory\n{0}", ex.Message));
			}
			this.Cursor = Cursors.Default;
		}

		private void mnuParameterConformityActive_Click(object sender, EventArgs e)
		{
			this.GenerateReport(ReportManager.DetailLevel.ParameterConformityByReport);
		}

		private void mnuParameterConformityAll_Click(object sender, EventArgs e)
		{
			this.GenerateReport(ReportManager.DetailLevel.ParameterConformityAllReports);
		}

		private void mnuAttributeConformityActive_Click(object sender, EventArgs e)
		{
			this.GenerateReport(ReportManager.DetailLevel.AttributeConformityByReport);
		}

		private void mnuAttributeConformityAll_Click(object sender, EventArgs e)
		{
			this.GenerateReport(ReportManager.DetailLevel.AttributeConformityAllReports);
		}

		private void mnuDetailComparison_Click(object sender, EventArgs e)
		{
			this.GenerateReport(ReportManager.DetailLevel.DetailedParameterComparison);
		}

		private void mnuLoadTemplate_Click(object sender, EventArgs e)
		{
			OpenFileDialog ofd = new OpenFileDialog();
			if (!string.IsNullOrEmpty(this._defaultDir))
			{
				ofd.InitialDirectory = this._defaultDir;
			}
			else
			{
				ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
			}
			ofd.Filter = "XML Files (*.xml)|*.xml|Report Definitions Files (*.rdl)|*.rdl";

			DialogResult dr = ofd.ShowDialog();
			if (dr == DialogResult.OK)
			{
				this._reportManager.LoadTemplate(ofd.FileName);
			}
			this.mnuUtilities.Enabled = true;
			this.grpFilterBy.Enabled = true;
		}

		private void mnuAddNewReportParameter_Click(object sender, EventArgs e)
		{
			if (this._reportManager.ActiveReport != null)
			{
				string name = this._reportManager.ActiveReport.CreateNewParameter();
				if (!this.lstReportParameterList.Items.Contains(name))
				{
					this.lstReportParameterList.Items.Add(name);
				}

				ReportManager.SaveChanges(this._reportManager.ActiveReport);

				this.lstReportParameterList.SelectedItem = name;
			}
		}

		private void cxmParmList_Opening(object sender, CancelEventArgs e)
		{
			this.deleteParameterToolStripMenuItem.Visible = (this.lstReportParameterList.SelectedIndex > -1);
		}

		#endregion

		#region	..... LIST EVENTS

		private void lstReportList_SelectedIndexChanged(object sender, EventArgs e)
		{
			this.Verify(this._reportManager.ActiveReport);
			
			if (this._reportManager.ActiveReport != null)
			{
				this._reportManager.ActiveReport.PropertyChanged -= this.ActiveReport_PropertyChanged;
			}

			string reportName = lstReportList.SelectedItem.ToString();
			if (this._reportManager.Reports.ContainsKey(reportName))
			{
				this._reportManager.ActiveReport = this._reportManager.Reports[reportName];
			}
			if (this._reportManager.ActiveReport != null)
			{
				this._reportManager.ActiveReport.PropertyChanged += this.ActiveReport_PropertyChanged;
				this.txtReportPath.Text = string.Format("{0}\\{1}", this._currDir, reportName);
			}

			if (this._selectedParameter != null)
			{
				this._prevParm = this._selectedParameter.Name;
			}
			else if (!string.IsNullOrEmpty(this.txtFilterByParmName.Text))
			{
				this._prevParm = this.txtFilterByParmName.Text;
			}

			this.ResetParameters();
			this.ToggleStateButtons(false);
			this.ToggleActionButtons();

			foreach (KeyValuePair<string, Parameter> kvp in this._reportManager.ActiveReport.Parameters)
			{
				this.lstReportParameterList.Items.Add(kvp.Key);
				if (this._prevParm == kvp.Key)
				{
					this.lstReportParameterList.SelectedItem = kvp.Key;
				}
			}

			this._prevParm = null;
			this.lstReportParameterList.Enabled = true;
		}

		private void lstReportParameterList_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				this.Verify(this._reportManager.ActiveReport);

				if (this.lstReportParameterList.SelectedIndex == -1)
				{
					this._selectedParameter = null;
					this.ResetReportParameterSettings();
				}
				else
				{
					this._selectedParameter = this._reportManager.ActiveReport.Parameters[this.lstReportParameterList.Text];
					this.ResetReportParameterSettings();
					this.PopulateReportParameterSettings();

					if (this.lstTemplateParameterList.Items.Contains(this.lstReportParameterList.Text))
					{
						if (this.lstTemplateParameterList.Text != this.lstReportParameterList.Text)
						{
							this.lstTemplateParameterList.SelectedItem = this.lstReportParameterList.Text;
						}
					}
					else
					{
						this.lstTemplateParameterList.SelectedIndex = -1;
					}
				}
				this.ToggleActionButtons();
				this.HighlightDifferences();
			}
		}

		private void lstReportParameterList_OnKeyDown(object sender, KeyEventArgs e)
		{
			base.OnKeyDown(e);
			if (e.KeyCode == Keys.Delete)
			{
				//confirm delete
				DialogResult dr = MessageBox.Show("Are you sure you wish to delete this parameter? This action cannot be undone.", 
					"Delete Parameter?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);

				if (dr == DialogResult.Yes)
				{
					int idx = this.lstReportParameterList.SelectedIndex;
					this._reportManager.ActiveReport.DeleteParameter(this.lstReportParameterList.Text);
					this.lstReportParameterList.Items.RemoveAt(idx);

					if (idx >= 0 && idx < this.lstReportParameterList.Items.Count)
					{
						this.lstReportParameterList.SelectedIndex = idx;
					}
					else if (idx < 0)
					{
						this.lstReportParameterList.SelectedIndex = 0;
					}
					else
					{
						this.lstReportParameterList.SelectedIndex = this.lstReportParameterList.Items.Count - 1;
					}
				}
			}
		}

		private void lstTemplateParameterList_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				this.Verify(this._reportManager.Template);

				if (this.lstTemplateParameterList.SelectedIndex == -1)
				{
					this._templateParameter = null;
					this.ResetTemplateParameterSettings();
				}
				else
				{
					this._templateParameter = this._reportManager.Template.Parameters[this.lstTemplateParameterList.Text];
					this.ResetTemplateParameterSettings();
					this.PopulateTemplateParameterSettings();

					if (this.lstReportParameterList.Items.Contains(this.lstTemplateParameterList.Text))
					{
						if (this.lstReportParameterList.Text != this.lstTemplateParameterList.Text)
						{
							this.lstReportParameterList.SelectedItem = this.lstTemplateParameterList.Text;
						}
					}
					else
					{
						this.lstReportParameterList.SelectedIndex = -1;
					}
				}
				this.ToggleActionButtons();
				this.HighlightDifferences();
			}
		}

		#endregion

		#region	..... RADIO BUTTON EVENTS

		private void rdoReportParameterValidValuesNonQueried_Click(object sender, EventArgs e)
		{
			this.pnlReportParameterValidValuesQueried.Visible = false;
			this.pnlReportParameterValidValuesNonQueried.Visible = true;

			if (this._selectedParameter.ValidValues == null || this._selectedParameter.ValidValues.ValuesList == null)
			{
				this._selectedParameter.CreateValidValues();
			}

			if (this.grdReportParameterValidValuesList.DataSource == null)
			{
				this.grdReportParameterValidValuesList.DataSource = this._selectedParameter.ValidValues.ValuesList;
			}
		}

		private void rdoReportParameterValidValuesQueried_Click(object sender, EventArgs e)
		{

			this.pnlReportParameterValidValuesQueried.Visible = true;
			this.pnlReportParameterValidValuesNonQueried.Visible = false;

			DataSet ds = this._selectedParameter.ValuesDataSet;

			if (ds != null)
			{
				this.PopulateReportParameterDataSetControls(ds, ValueType.ValidValues);
			}
			else
			{
				//create list of all available DataSets that exist within the current report...
				List<string> dsNames = new List<string>(this._reportManager.ActiveReport.DataSets.Keys);

				//populate the ValidValues DataSet combobox with the resulting list...
				this.cboReportParameterValidValuesDataset.Items.AddRange(dsNames.ToArray());
			}
		}

		private void rdoReportParameterDefaultNonQueried_Click(object sender, EventArgs e)
		{
			this.pnlReportParameterDefaultQueried.Visible = false;
			this.pnlReportParameterDefaultNonQueried.Visible = true;

			if (this._selectedParameter.DefaultValue == null || this._selectedParameter.DefaultValue.ValidValues == null)
			{
				this._selectedParameter.CreateDefaultValues();
			}

			if (this.grdReportParameterDefaultNonQueried.DataSource == null)
			{
				this.grdReportParameterDefaultNonQueried.DataSource = this._selectedParameter.DefaultValue.ValidValues.DefaultList;
			}

		}

		private void rdoReportParameterDefaultQueried_Click(object sender, EventArgs e)
		{
			this.pnlReportParameterDefaultQueried.Visible = true;
			this.pnlReportParameterDefaultNonQueried.Visible = false;

			DataSet ds = this._selectedParameter.DefaultDataSet;

			if (ds != null)
			{
				this.PopulateReportParameterDataSetControls(ds, ValueType.DefaultValues);
			}
			else
			{
				//create list of all available DataSets that exist within the current report...
				List<string> dsNames = new List<string>(this._reportManager.ActiveReport.DataSets.Keys);

				//populate the ValidValues DataSet combobox with the resulting list...
				this.cboReportParameterDefaultDataset.Items.AddRange(dsNames.ToArray());
			}
		}

		private void rdoReportParameterDefaultNull_Click(object sender, EventArgs e)
		{
			this._selectedParameter.DefaultValue = null;

			//panel visibility and radio button selection
			this.rdoReportParameterDefaultNull.Checked = true;
			this.pnlReportParameterDefaultNonQueried.Visible = false;
			this.pnlReportParameterDefaultQueried.Visible = false;
		}

		#region	.......... TEMPLATE PARAMETER BUTTON CLICK EVENTS...
		private void rdoTemplateParameterValidValuesNonQueried_Click(object sender, EventArgs e)
		{
			this.pnlTemplateParameterValidValuesNonQueried.Visible = true;
			this.pnlTemplateParameterValidValuesQueried.Visible = false;
		}
		private void rdoTemplateParameterValidValuesQueried_Click(object sender, EventArgs e)
		{
			this.pnlTemplateParameterValidValuesNonQueried.Visible = false;
			this.pnlTemplateParameterValidValuesQueried.Visible = true;
		}
		private void rdoTemplateParameterDefaultNonQueried_Click(object sender, EventArgs e)
		{
			this.pnlTemplateParameterDefaultQueried.Visible = false;
			this.pnlTemplateParameterDefaultNonQueried.Visible = true;
		}
		private void rdoTemplateParameterDefaultQueried_Click(object sender, EventArgs e)
		{
			this.pnlTemplateParameterDefaultQueried.Visible = true;
			this.pnlTemplateParameterDefaultNonQueried.Visible = false;
		}
		private void rdoTemplateParameterDefaultNull_Click(object sender, EventArgs e)
		{
			this.pnlTemplateParameterDefaultQueried.Visible = false;
			this.pnlTemplateParameterDefaultNonQueried.Visible = false;
		}
		#endregion

		#endregion

		#region	..... CHECKBOX EVENTS

		private void cbxReportParameterIsHidden_CheckedChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cbxReportParameterIsHidden.Checked != this._selectedParameter.Hidden)
			{
				this._selectedParameter.Hidden = this.cbxReportParameterIsHidden.Checked;
				this.HighlightDifferences();
			}
		}

		private void cbxReportParameterIsInternal_CheckedChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cbxReportParameterIsInternal.Checked != this._selectedParameter.Internal)
			{
				if (this.cbxReportParameterIsInternal.Checked)
				{
					this.cbxReportParameterIsHidden.Checked = true;
					this.cbxReportParameterIsHidden.Enabled = false;
					this.txtReportParameterPrompt.Text = string.Empty;
				}
				else
				{
					this.txtReportParameterPrompt.Text = this._selectedParameter.Name;
					this.cbxReportParameterIsHidden.Enabled = true;
				}
				this.HighlightDifferences();
			}
		}

		private void cbxReportParameterIsMultiValue_CheckedChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cbxReportParameterIsMultiValue.Checked != this._selectedParameter.MultiValue)
			{
				this._selectedParameter.MultiValue = this.cbxReportParameterIsMultiValue.Checked;
				this.HighlightDifferences();
			}
		}

		private void cbxReportParameterAllowsNull_CheckedChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cbxReportParameterAllowsNull.Checked != this._selectedParameter.Nullable)
			{
				this._selectedParameter.Nullable = this.cbxReportParameterAllowsNull.Checked;
				this.HighlightDifferences();
			}
		}

		private void cbxReportParameterAllowsBlank_CheckedChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cbxReportParameterAllowsBlank.Checked != this._selectedParameter.AllowBlank)
			{
				this._selectedParameter.AllowBlank = this.cbxReportParameterAllowsBlank.Checked;
				this.HighlightDifferences();
			}
		}

		#endregion

		#region	..... COMBOBOX EVENTS

		/// <summary>
		/// Handles changes to the selected index of the Report Parameter Data Type combobox, and propogates this change to
		/// the underlying report parameter's data-type property.
		/// </summary>
		private void cboReportParameterDataType_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				ReportParameterTypeDataType rpdt = (ReportParameterTypeDataType)Enum.Parse(typeof(ReportParameterTypeDataType), this.cboReportParameterDataType.SelectedItem.ToString(), true);
				if (this._selectedParameter.DataType != rpdt)
				{
					this._selectedParameter.DataType = rpdt;
					this.HighlightDifferences();
				}
			}
		}

		private void cboReportParameterValidValuesDataset_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				string dsName = this.cboReportParameterValidValuesDataset.Text;
				if (this._selectedParameter.ValuesDataSet == null || this._selectedParameter.ValuesDataSet.Name != dsName)
				{
					DataSet ds = null;
					if (!string.IsNullOrEmpty(dsName) && this._reportManager.ActiveReport.DataSets.ContainsKey(dsName))
					{
						ds = this._reportManager.ActiveReport.DataSets[dsName];
					}

					this._selectedParameter.CreateValidValues(ds);

					//Reset selected label / value fields
					this.PopulateReportParameterDataFields(ds, ValueType.ValidValues);
					this.PopulateReportParameterDataQuery(ds, ValueType.ValidValues);

					this.HighlightDifferences();
				}
			}
		}

		private void cboReportParameterValidValuesLabelField_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cboReportParameterValidValuesLabelField.Text != this._selectedParameter.ValidValues.DataSetReference.LabelField)
			{
				this._selectedParameter.ValidValues.DataSetReference.LabelField = this.cboReportParameterValidValuesLabelField.Text;
				this.HighlightDifferences();
			}
		}

		private void cboReportParameterValidValuesValueField_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cboReportParameterValidValuesValueField.Text != this._selectedParameter.ValidValues.DataSetReference.ValueField)
			{
				this._selectedParameter.ValidValues.DataSetReference.ValueField = this.cboReportParameterValidValuesValueField.Text;
				this.HighlightDifferences();
			}
		}

		private void cboReportParameterValidValuesCommandType_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				QueryTypeCommandType qtct = (QueryTypeCommandType)Enum.Parse(typeof(QueryTypeCommandType), this.cboReportParameterValidValuesCommandType.Text);
				if (this._selectedParameter.ValuesDataSet.Query.CommandType != qtct)
				{
					this._selectedParameter.ValuesDataSet.Query.CommandType = qtct;
					this.HighlightDifferences();
				}
			}
		}

		private void cboReportParameterDefaultDataset_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				string dsName = this.cboReportParameterDefaultDataset.Text;
				if (this._selectedParameter.DefaultDataSet == null || this._selectedParameter.DefaultDataSet.Name != dsName)
				{
					DataSet ds = null;
					if (!string.IsNullOrEmpty(dsName) && this._reportManager.ActiveReport.DataSets.ContainsKey(dsName))
					{
						ds = this._reportManager.ActiveReport.DataSets[dsName];
					}

					this._selectedParameter.CreateDefaultValues(ds);

					//Reset selected label / value fields
					this.PopulateReportParameterDataFields(ds, ValueType.DefaultValues);
					this.PopulateReportParameterDataQuery(ds, ValueType.DefaultValues);

					this.HighlightDifferences();
				}
			}
		}

		private void cboReportParameterDefaultValueField_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing && this.cboReportParameterDefaultValueField.Text != this._selectedParameter.DefaultValue.ValidValues.DataSetReference.ValueField)
			{
				this._selectedParameter.DefaultValue.ValidValues.DataSetReference.ValueField = this.cboReportParameterDefaultValueField.Text;
				this.HighlightDifferences();
			}
		}

		private void cboReportParameterDefaultCommandType_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!this._initializing)
			{
				QueryTypeCommandType qtct = (QueryTypeCommandType)Enum.Parse(typeof(QueryTypeCommandType), this.cboReportParameterDefaultCommandType.Text);
				if (this._selectedParameter.DefaultDataSet.Query.CommandType != qtct)
				{
					this._selectedParameter.DefaultDataSet.Query.CommandType = qtct;
					this.HighlightDifferences();
				}
			}
		}

		#endregion

		#region	..... TEXTBOX EVENTS

		#region .......... REPORT PARAMETERS

		private void txtReportParameterName_LostFocus(object sender, EventArgs e)
		{
			if (!this._initializing && this.txtReportParameterName.Text != this._selectedParameter.Name)
			{
				if (string.IsNullOrEmpty(this.txtReportParameterName.Text))
				{
					this.txtReportParameterName.Text = this._selectedParameter.Name;
				}
				else
				{
					this._initializing = true;
					int idx = this.lstReportParameterList.Items.IndexOf(this._selectedParameter.Name);
					this.lstReportParameterList.Items[idx] = this.txtReportParameterName.Text;
					this._selectedParameter.Name = this.txtReportParameterName.Text;

					if (this._reportManager.Template.Parameters.ContainsKey(this._selectedParameter.Name))
					{
						this.lstTemplateParameterList.SelectedItem = this._selectedParameter.Name;
					}
					else
					{
						this._templateParameter = null;
						this.ResetTemplateParameterSettings();
					}
					this._initializing = false;
				}
			}
		}

		private void txtReportParameterPrompt_LostFocus(object sender, EventArgs e)
		{
			if (!this._initializing && this.txtReportParameterPrompt.Text != this._selectedParameter.Prompt)
			{
				this._selectedParameter.Prompt = this.txtReportParameterPrompt.Text;
				this.HighlightDifferences();
			}
		}

		private void rtbReportParameterValidValuesCommandText_LostFocus(object sender, EventArgs e)
		{
			if (!this._initializing && this.rtbReportParameterValidValuesCommandText.Text != this._selectedParameter.ValuesDataSet.Query.CommandText)
			{
				this._selectedParameter.ValuesDataSet.Query.CommandText = this.rtbReportParameterValidValuesCommandText.Text;
				this.HighlightDifferences();
			}
		}

		private void rtbReportParameterDefaultCommandText_LostFocus(object sender, EventArgs e)
		{
			if (!this._initializing && this.rtbReportParameterDefaultCommandText.Text != this._selectedParameter.DefaultDataSet.Query.CommandText)
			{
				this._selectedParameter.DefaultDataSet.Query.CommandText = this.rtbReportParameterDefaultCommandText.Text;
				this.HighlightDifferences();
			}
		}

		#endregion

		#region .......... FILTER BY

		private void txtFilterBy_OnEnter(object sender, EventArgs e)
		{
			if (sender is TextBox)
			{
				((TextBox)sender).SelectAll();
			}
		}

		private void txtFilterBy_OnKeyDown(object sender, KeyEventArgs e)
		{
			if (sender is TextBox && e.KeyCode == Keys.Enter)
			{
				this.btnFilterBy_Click(null, null);
			}
		}

		#endregion

		#endregion

		#region ..... BUTTON EVENTS

		private void btnFilterBy_Click(object sender, EventArgs e)
		{
			this.Verify(this._reportManager.ActiveReport);

			this.ResetReports();
			this.ResetParameters();

			string parmName = this.txtFilterByParmName.Text;
			string datasetName = this.txtFilterByDatasetName.Text;
			string sprocName = this.txtFilterBySprocName.Text;
			bool matchFound;

			foreach (ReportWrapper rw in this._reportManager.Reports.Values)
			{
				matchFound = false;

				if (rw.Parameters != null)
				{
					foreach (Parameter p in rw.Parameters.Values)
					{
						if (!string.IsNullOrEmpty(parmName))
						{
							if (!p.Name.Equals(parmName, StringComparison.CurrentCultureIgnoreCase))
							{
								continue;
							}
						}
						if (!string.IsNullOrEmpty(datasetName))
						{
							if (!p.ReferencesDataSet(datasetName))
							{
								continue;
							}
						}
						if (!string.IsNullOrEmpty(sprocName))
						{
							if (!p.ReferencesSproc(sprocName))
							{
								continue;
							}
						}
						matchFound = true;
						break;
					}
					if (matchFound)
					{
						this.lstReportList.Items.Add(rw.Name);
					}
				}
				if (!matchFound && rw.DataSets != null)
				{
					foreach (DataSet ds in rw.DataSets.Values)
					{
						if (!string.IsNullOrEmpty(sprocName))
						{
							if (ds.Query != null && ds.Query.CommandText.Equals(sprocName, StringComparison.InvariantCultureIgnoreCase))
							{
								matchFound = true;
								break;
							}
						}
					}
					if (matchFound)
					{
						this.lstReportList.Items.Add(rw.Name);
					}
				}
			}
		}

		private void btnClear_Click(object sender, EventArgs e)
		{
			this.Verify(this._reportManager.ActiveReport);

			ResetAll();

			foreach (KeyValuePair<string, ReportWrapper> entry in this._reportManager.Reports)
			{
				this.lstReportList.Items.Add(entry.Key);
			}
		}

		private void btnCopyTemplateToParameter_Click(object sender, EventArgs e)
		{
			if (this._templateParameter != null && this._selectedParameter != null && this._templateParameter.Name == this._selectedParameter.Name)
			{
				this._reportManager.ActiveReport.CreateParameterCopy(this._templateParameter);
				this._selectedParameter = this._reportManager.ActiveReport.Parameters[this._templateParameter.Name];
				this.ResetReportParameterSettings();
				this.PopulateReportParameterSettings();
				this.ToggleActionButtons();
				this.HighlightDifferences();
			}
		}

		private void btnCopyParameterToTemplate_Click(object sender, EventArgs e)
		{
			if (this._templateParameter != null && this._selectedParameter != null && this._templateParameter.Name == this._selectedParameter.Name)
			{
				this._reportManager.Template.CreateParameterCopy(this._selectedParameter);
				this._templateParameter = this._reportManager.Template.Parameters[this._selectedParameter.Name];
				this.ResetTemplateParameterSettings();
				this.PopulateTemplateParameterSettings();
				this.ToggleActionButtons();
				this.HighlightDifferences();
			}
		}

		private void btnAddTemplateParameterToReport_Click(object sender, EventArgs e)
		{
			if (!this.lstReportParameterList.Items.Contains(this._templateParameter.Name))
			{
				this._reportManager.ActiveReport.CreateParameterCopy(this._templateParameter);
				this.lstReportParameterList.Items.Add(this._templateParameter.Name);
				this.lstReportParameterList.SelectedItem = this._templateParameter.Name;
			}
		}

		private void btnAddReportParameterToTemplate_Click(object sender, EventArgs e)
		{
			if (!this.lstTemplateParameterList.Items.Contains(this._selectedParameter.Name))
			{
				this._reportManager.Template.CreateParameterCopy(this._selectedParameter);
				this.lstTemplateParameterList.Items.Add(this._selectedParameter.Name);
				this.lstTemplateParameterList.SelectedItem = this._selectedParameter.Name;
			}
		}

		private void btnSaveChanges_Click(object sender, EventArgs e)
		{
			if (this._reportManager != null)
			{
				if (this._reportManager.ActiveReport != null && this._reportManager.ActiveReport.IsDirty)
				{
					ReportManager.SaveChanges(this._reportManager.ActiveReport);
				}
				if (this._reportManager.Template != null && this._reportManager.Template.IsDirty)
				{
					ReportManager.SaveChanges(this._reportManager.Template);
				}
			}
			this.ToggleStateButtons(false);
		}

		private void btnReset_Click(object sender, EventArgs e)
		{
			if (this._reportManager != null)
			{
				if (this._reportManager.ActiveReport != null && this._reportManager.ActiveReport.IsDirty)
				{
					this._reportManager.ActiveReport.RestoreState();
				}
				if (this._reportManager.Template != null && this._reportManager.Template.IsDirty)
				{
					this._reportManager.Template.RestoreState();
				}
			}
		}

		#endregion

		#region ..... TAB EVENTS

		private void tbcReportParameter_SelectedIndexChanged(object sender, EventArgs e)
		{
			tbcTemplateParameter.SelectedIndex = tbcReportParameter.SelectedIndex;
		}

		#endregion

		void ActiveReport_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			this.ToggleStateButtons(true);
		}

		#endregion

		#region REPORT GENERATION METHODS

		private void GenerateReport(ReportManager.DetailLevel dl)
		{
			string path = this.SaveAs(dl);
			if (!string.IsNullOrEmpty(path))
			{
				this._reportManager.GenerateComparisonReport(path, dl);
			}
		}

		private string SaveAs(ReportManager.DetailLevel dl)
		{
			SaveFileDialog dlg = new SaveFileDialog();
			dlg.DefaultExt = ".txt";
			dlg.FileName = string.Format("{0}.txt", Enum.GetName(typeof(ReportManager.DetailLevel), dl));
			dlg.Filter = "Text files (*.txt)|*.txt";
			dlg.RestoreDirectory = false;
			dlg.InitialDirectory = (string.IsNullOrEmpty(this._saveAsDir) ? this._currDir : this._saveAsDir);
			dlg.Title = "Save To...";
			dlg.ValidateNames = true;
			DialogResult dr = dlg.ShowDialog();
			if (dr == DialogResult.OK)
			{
				this._saveAsDir = dlg.FileName.Substring(0, dlg.FileName.LastIndexOf("\\"));
				return dlg.FileName;
			}
			else
			{
				return null;
			}

		}

		#endregion

	}
}